# -*- coding: utf-8 -*-
# copyright (c) 2007
# Kazumasa Suzuki

import os
from zope.interface import implements
from twisted.application import internet
from twisted.internet import protocol, defer
from twisted.mail import smtp

#from mtaxiom import JST, MtMessage, MtRoom, MtUser, MidtownManager
#from midtown.mtaxiom import *
from mtaxiom import *
#import midtown.mtaxiom
#import midtown

import re

class FileMessage(object):
    implements(smtp.IMessage)

    def __init__(self, fileObj):
        self.fileObj = fileObj

    def lineReceived(self, line):
        self.fileObj.write(line + '\n')

    def eomReceived(self):
        self.fileObj.close()
        return defer.succeed(None)

    def connectionLost(self):
        self.fileObj.close()
        os.remove(self.fileObj.name)

class DbMessage(object):
    implements(smtp.IMessage)

    def __init__(self, mm):
        self.store = mm.store
        self.lines = []
        self.subre = re.compile("[Ss]ubject: (.*)")
        self.subject = ''
        self.fromre = re.compile("[Fr]rom: (.*)")
        self.fromaddr = ''
        self.tore = re.compile("[Tt]o: (.*)") # too simple, though
        self.toaddr = ''

    def lineReceived(self, line):
        self.lines.append(line + '\n')
        subject = self.subre.match(line)
        fromaddr = self.fromre.match(line)
        toaddr = self.tore.match(line)
        if subject:
            self.subject = subject.groups()
        if fromaddr:
            self.fromaddr = fromaddr.groups()
        if toaddr:
            self.toadr = toaddr.groups()

    def eomReceived(self):
        aRoom = MtRoom(name = unicode(self.toaddr),
                       store = self.store)

        aMsg = MtMessage(who = unicode(self.fromaddr),
                         subject = unicode(self.subject),
                         body = unicode(self.lines),
                         room = aRoom,
                         roomname = aRoom.name,
                         store = self.store)
                  
        aUser = MtUser(username = unicode(self.fromaddr),
                       nickname = unicode(self.fromaddr),
                       store = self.store)

        return defer.succeed(None)

    def connectionLost(self):
        self.store.close()


class MidtownDelivery(object):
    implements(smtp.IMessageDelivery)
    counter = 0

    def __init__(self, mm):
        self.mm = mm

    def old_validateTo(self, user):
        fileName = 'tutorial-smtp.' + str(self.counter)
        self.counter += 1
        return lambda: FileMessage(file(fileName, 'w'))

    def validateTo(self, user):
        return lambda: DbMessage(self.mm)

    def validateFrom(self, helo, origin):
        return origin

    def receivedHeader(self, helo, origin, recipients):
        return 'Received: Midtown'

class MidtownDeliveryFactory(object):
    implements(smtp.IMessageDeliveryFactory)

    def __init__(self, mm):
        self.mm = mm

    def getMessageDelivery(self):
        return MidtownDelivery(self.mm)

class MidtownESMTPFactory(protocol.ServerFactory):
    protocol = smtp.ESMTP

    def __init__(self, mm):
        self.mm = mm

    def buildProtocol(self, addr):
        p = self.protocol()
        p.deliveryFactory = MidtownDeliveryFactory(self.mm)
        p.factory = self
        return p

__all__ = ["FileMessage", "DbMessage", "MidtownDelivery", "MidtownDeliveryFactory",
           "MidtownESMTPFactory"]


#smtpServerFactory = MidtownESMTPFactory()

#smtpServerService = internet.TCPServer(2025, smtpServerFactory)
#smtpServerService.setServiceParent(application)




if __name__ == "__main__":
    mm = MidtwonManager()
    print 'done'
